﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using MuYue.Common;

namespace MuYue.Log {

    /// <summary>
    /// 日志级别
    /// </summary>
    public enum LogLevel {
        调试 = 0,
        信息 = 1,
        警告 = 2,
        错误 = 3
    }

    /// <summary>
    /// 日志实际调用的类 是对Log的核心处理的封装
    /// 1.程序启动的时候初始化一次
    /// 2.程序结束的时候释放掉资源
    /// 3.采用约定大于配置的方式 有配置项的采用配置内容 没有配置的采用约定的内容
    /// </summary>
    public static class LogService {
        /// <summary>
        /// 日志处理对象
        /// </summary>
        private static ThreadModel<LogMessage> Logger;

        /// <summary>
        /// 日志功能关闭标志
        /// </summary>
        private static bool _closed;

        /// <summary>
        /// 格式化消息写入
        /// 该方式写入的是日志级别为:LogLevel.信息
        /// </summary>
        /// <param name="format">日志内容格式文本</param>
        /// <param name="arg">日志内容填充数组</param>
        public static void Write(string format, params object[] arg) {
            Write(string.Format(format, arg));
        }

        /// <summary>
        /// 格式化写入特定等级的消息
        /// </summary>
        /// <param name="logLevel">日志级别</param>
        /// <param name="format">日志内容格式文本</param>
        /// <param name="arg">日志内容填充数组</param>
        public static void Write(LogLevel logLevel, string format, params object[] arg) {
            Write(string.Format(format, arg), logLevel);
        }


        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="strMsg"></param>
        public static void Warn(string strMsg) {
            Write(strMsg, Log.LogLevel.警告);
        }

        /// <summary>
        /// 采用格式化的方式输出警告信息
        /// </summary>
        /// <param name="strMsg"></param>
        /// <param name="args"></param>

        public static void Warn(string strMsg, params object[] args) {
            Warn(string.Format(strMsg, args));
        }

        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="strMsg"></param>
        public static void Debug(string strMsg) {
            Write(strMsg, Log.LogLevel.调试);
        }


        /// <summary>
        /// 采用格式化的方式输出调试信息
        /// </summary>
        /// <param name="strMsg"></param>
        /// <param name="args"></param>
        public static void Debug(string strMsg, params object[] args) {
            Debug(string.Format(strMsg, args));
        }



        /// <summary>
        /// 消息写入
        /// </summary>
        /// <param name="strMessage"></param>
        /// <param name="logLevel"></param>
        public static void Write(string strMessage, LogLevel logLevel = LogLevel.信息) {
            if (Logger != null)
                Logger.Append(new LogMessage(strMessage, logLevel));
        }


        /// <summary>
        /// 停止日志服务停止之后日志服务将无法进行调用了
        /// </summary>
        public static void Stop() {
            if (!_closed) {
                Logger.Dispose();
                _closed = true;
                Logger = null;
            }
        }

        /// <summary>
        /// 初始化日志信息
        /// </summary>
        /// <param name="fileName"></param>
        public static void Start() {
            if (Logger == null) {
                Logger = new ThreadModel<LogMessage>();
                Logger.DealModelEvent += RecordMsgByFile;
                Logger.DealModelEvent += ShowMsgByConsole;
                _closed = false;
            }
        }

        public static TextWriter Out { set; get; }

        /// <summary>
        /// 使用控制台展示LogMessage
        /// </summary>
        /// <param name="iLogMessage"></param>
        private static void ShowMsgByConsole(LogMessage logMessage) {
            if (Out != null) {
                //处理的方式是写出文本信息
                var strMsg = string.Format("[{0}] [{1}]：{2}", logMessage.CreateTime.ToString("yy-MM-dd hh:mm:ss"), logMessage.MsgLevel, logMessage.Content);
                Out.WriteLine(strMsg);
            }
        }


        /// <summary>
        /// 使用文件记录日志
        /// </summary>
        /// <param name="logMessage"></param>
        private static void RecordMsgByFile(LogMessage logMessage) {
            if (logMessage.MsgLevel < Configuration.LogSaveLowestLevel)
                return;
            //写文件信息 1.检查目录 2.创建文件 3.写入信息 使用logLevel来实现分类存放
            var fileName = string.Format(@"{2}\{0}_{1}.log", DateTime.Today.ToString("yy-MM-dd"), logMessage.MsgLevel, Configuration.LogSavePath);
            if (!Directory.Exists(Configuration.LogSavePath)) {
                Directory.CreateDirectory(Configuration.LogSavePath);
            }
            //由于日志按照日期进行存放 所以不需要日期信息
            var str = string.Format("[{0}] [{1}]：{2}\r\n", logMessage.CreateTime.ToString("hh:mm:ss"), logMessage.MsgLevel, logMessage.Content);
            File.AppendAllText(fileName, str);
        }
    }
}
